const getScrollParent =  (el)=>{
    let parent = el.parentNode;
    while(parent){
        if(/(scroll)|(auto)/.test(getComputedStyle(parent)['overflow'])){
            return parent;
        }
        parent = parent.parentNode;
    }
    return window;
}
const loadImageAsync = (src,resolve,reject)=>{
    let image = new Image();
    image.src = src;
    image.onload = resolve;
    image.onerror = reject;
}
const Lazy = (Vue)=>{
    class ReactiveListener{ //每一个图片元素都构造成一个类的实例
        constructor({el,src,options,elRender}){
            this.el = el;
            this.src = src;
            this.options = options;
            this.elRender = elRender;
            this.state = {loading: false};//没有加载过
        }
        checkInView(){
            let {top} = this.el.getBoundingClientRect();
            return top < window.innerHeight * (this.options.preload || 1.3);
        }
        load(){
            this.elRender(this,'loading');
            //懒加载的核心就是new image
            loadImageAsync(this.src,()=>{
                this.state.loading = true;
                this.elRender(this,'finish');
            },()=>{
                this.elRender(this,'error');
            })
        }
    }
    return class LazyClass{
        constructor(options){
            this.options = options;
            this.bindHandler = false;
            this.listenerQuene = []
        }
        handleLazyLoad(){
            console.log('ok-------- ')
            //检测是否应该显示这个图片
            //计算当前图片的位置
            this.listenerQuene.forEach(listener=>{
                if(!listener.state.loading){
                    let catIn =  listener.checkInView();
                    catIn && listener.load();
                }
            })
        }
        elRender(listener,state){//渲染方法
            let el = listener.el;
            let src = '';
            switch(state){
                case 'loading':
                    src = listener.options.loading || '';
                    break;
                case 'error':
                    src = listener.options.error || '';
                    break;
                default:
                    src = listener.src;
                    break;
            }
            el.setAttribute('src',src);
        }
        add(el,bindings,vnode){
            //找到父元素
            Vue.nextTick(()=>{
                //带有滚动的盒子
                let scrollParent = getScrollParent(el);
                if(scrollParent && !this.bindHandler){
                    console.log(scrollParent)
                    this.bindHandler = true;
                    scrollParent.addEventListener('scroll',this.handleLazyLoad.bind(this));
                }
                //判断当前元素是否在容器可视区域中，如果不是就不用渲染
                const listener = new ReactiveListener({
                    el,
                    src:bindings.value,
                    options: this.options,
                    elRender: this.elRender.bind(this)
                });
                // 所有的图片创建实例 放到数组中
                this.listenerQuene.push(listener);
                this.handleLazyLoad();
            })
        }
    }
}
const VueLazyload = {
    install(Vue,options){
        console.log(Vue,options)
        //把所有逻辑进行封装，把类封装到函数中
        const LazyClass = Lazy(Vue);
        const lazy = new LazyClass(options)
        Vue.directive('lazy',{
            bind:lazy.add.bind(lazy)
        })
    }
}
//通过节流优化滚动
